package cn.qianxun.meta.feign.feign.config;

import cn.qianxun.meta.common.core.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import cn.qianxun.meta.common.core.constant.FeignConstant;
import cn.qianxun.meta.common.core.constant.TenantConstant;
import cn.qianxun.meta.common.core.context.TenantContextHolder;
import cn.qianxun.meta.common.core.utils.trace.TraceUtil;
import feign.RequestInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.context.annotation.Bean;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Map;

import static org.apache.http.HttpHeaders.TRANSFER_ENCODING;

/**
 * feign拦截器
 *
 * @author fuzhilin
 * @date 2021-8-5
 */
@Slf4j
public class FeignInterceptorConfiguration {

    /**
     * 使用feign client发送请求时，传递tenantId和traceId
     *
     * @return
     */
    @Bean
    public RequestInterceptor requestInterceptor() {
        return requestTemplate -> {
            String url = requestTemplate.url();
            String tenantId = TenantContextHolder.getTenantId();
            if (StringUtils.isNotBlank(tenantId)) {
                requestTemplate.header(TenantConstant.meta_TENANT_ID, tenantId);
            }
            log.info("feign interceptor header:{}", requestTemplate);

            Map<String, Collection<String>> queries = requestTemplate.queries();
            log.info("feign interceptor param:{}", JSON.toJSONString(queries));
            //传递日志traceId
            String traceId = MDC.get(FeignConstant.LOG_TRACE_ID);
            if (StringUtils.isBlank(traceId)) {
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                if (attributes != null) {
                    HttpServletRequest request = attributes.getRequest();
                    Enumeration<String> headerNames = request.getHeaderNames();
                    if (headerNames != null) {
                        String headerName = null;
                        while (headerNames.hasMoreElements()) {
                            headerName = headerNames.nextElement();
                            if (headerName.equalsIgnoreCase(FeignConstant.META_TRACE_ID)) {
                                traceId = request.getHeader(headerName);
                                requestTemplate.header(FeignConstant.META_TRACE_ID, traceId);
                                TraceUtil.mdcTraceId(traceId);
                            }
                            String values = request.getHeader(headerName);
                            //后期需要处理feign的调用也有些需要加token的问题。
                            if ("Authorization".equals(headerName) || "authorization".equals(headerName)) {
                                continue;
                            }
                            if ("Content-Type".equals(headerName) || "content-type".equals(headerName)) {
                                continue;
                            }
                            if ("Content-Length".equals(headerName) || "content-length".equals(headerName)) {
                                continue;
                            }
                            if (TRANSFER_ENCODING.equalsIgnoreCase(headerName)) {
                                continue;
                            }
                            requestTemplate.header(headerName, values);
                        }
                    }
                }
            } else {
                if (StringUtils.isNotBlank(traceId)) {
                    requestTemplate.header(FeignConstant.META_TRACE_ID, traceId);
                }
            }
        };
    }

}


